#include <QtCore/QCoreApplication>
#include <QDebug>
#include <QPoint>
#include <math.h>
#include "nd_polynom.h"


int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

	if(0)
	{
		int						p[2];
		nd_term<double,2>		t;
		nd_polynom<double,2>	f,g;

/*
  f = x3y2 - x2y3 + x
*/
		p[0] = 3; p[1] = 2;
		t = nd_term<double,2>( 1, p );
		f.add( t );

		p[0] = 2; p[1] = 3;
		t = nd_term<double,2>( -1, p );
		f.add( t );

		p[0] = 1; p[1] = 0;
		t = nd_term<double,2>( 1, p );
		f.add( t );

/*
  g = 3x4y + y2
*/
		p[0] = 4; p[1] = 1;
		t = nd_term<double,2>( 3, p );
		g.add( t );

		p[0] = 0; p[1] = 2;
		t = nd_term<double,2>( 1, p );
		g.add( t );


		nd_polynom<double,2>	s;

		f.chop(0);
		g.chop(0);

		nd_polynom<double,2>::spolynom( f, g, s );

		qDebug() << "f,g = ";
		f.print( qDebug() );
		g.print( qDebug() );
		qDebug() << "spolynom = ";
		s.print( qDebug() );
	}

	if(0)
	{
		int								p[2];
		nd_term<double,2>				t;
		nd_polynom<double,2>			f1,f2,f,r;
		nd_polynom_system<double,2>		s;

/*
  f1 = y2 - 1
*/
		p[0] = 0; p[1] = 2;
		t = nd_term<double,2>( 1, p );
		f1.add( t );

		p[0] = 0; p[1] = 0;
		t = nd_term<double,2>( -1, p );
		f1.add( t );
/*
  f2 = xy - 1
*/
		p[0] = 1; p[1] = 1;
		t = nd_term<double,2>( 1, p );
		f2.add( t );

		p[0] = 0; p[1] = 0;
		t = nd_term<double,2>( -1, p );
		f2.add( t );

		s.push_back( f1 );
		s.push_back( f2 );

/*
  f = x2y + xy2 + y2
*/
		p[0] = 2; p[1] = 1;
		t = nd_term<double,2>( 1, p );
		f.add( t );

		p[0] = 1; p[1] = 2;
		t = nd_term<double,2>( 1, p );
		f.add( t );

		p[0] = 0; p[1] = 2;
		t = nd_term<double,2>( 1, p );
		f.add( t );


		f1.chop(0);
		f2.chop(0);
		f.chop(0);

		qDebug() << "f1,f2 = ";
		f1.print( qDebug() );
		f2.print( qDebug() );
		qDebug() << "Reduce by f = ";
		f.print( qDebug() );

		s.reduce( f, r );

		qDebug() << "Reduced r = ";
		r.print( qDebug() );
	}

	{
		typedef double					T;
		int								p[2];
		nd_term<T,2>					t;
		nd_polynom<T,2>					f1,f2;
		nd_polynom_system<T,2>			s;
/*
 - 6x2 + 6x - 6y2 + 6y - 2
*/
		p[0] = 2; p[1] = 0;
		t = nd_term<T,2>( -6, p );
		f1.add( t );

		p[0] = 1; p[1] = 0;
		t = nd_term<T,2>( 6, p );
		f1.add( t );

		p[0] = 0; p[1] = 2;
		t = nd_term<T,2>( -6, p );
		f1.add( t );

		p[0] = 0; p[1] = 1;
		t = nd_term<T,2>( 6, p );
		f1.add( t );

		p[0] = 0; p[1] = 0;
		t = nd_term<T,2>( -2, p );
		f1.add( t );

/*
  4x3 - 6x2 - 4y3 + 6y2
*/
		p[0] = 3; p[1] = 0;
		t = nd_term<T,2>( 4, p );
		f2.add( t );

		p[0] = 2; p[1] = 0;
		t = nd_term<T,2>( -6, p );
		f2.add( t );

		p[0] = 0; p[1] = 3;
		t = nd_term<T,2>( -4, p );
		f2.add( t );

		p[0] = 0; p[1] = 2;
		t = nd_term<T,2>( 6, p );
		f2.add( t );

		f1.chop(0);
		f2.chop(0);

		s.push_back( f2 );
		s.push_back( f1 );

		qDebug() << "Input equations:";
		s.print( qDebug() );
		s.construct_groebner_basis();

		qDebug() << "Grobner basis:";
		s.print( qDebug() );

		s.construct_groebner_basis();

		qDebug() << "Grobner basis2:";
		s.print( qDebug() );

		s.minimize_groebner_basis();
		qDebug() << "Min Grobner basis:";
		s.print( qDebug() );
	}

	if(0)
	{
/*
f1 = x2 + y2 + z2 ,
f2 = x + y − z,
f3 = y + z2
*/
		int								p[3];
		nd_term<double,3>				t;
		nd_polynom<double,3>			f1,f2,f3;
		nd_polynom_system<double,3>		s;
/*
f1 = x2 + y2 + z2
*/
		p[0] = 2; p[1] = 0; p[2] = 0;
		t = nd_term<double,3>( 1, p );
		f1.add( t );

		p[0] = 0; p[1] = 2; p[2] = 0;
		t = nd_term<double,3>( 1, p );
		f1.add( t );

		p[0] = 0; p[1] = 0; p[2] = 2;
		t = nd_term<double,3>( 1, p );
		f1.add( t );
/*
f2 = x + y − z,
*/
		p[0] = 1; p[1] = 0; p[2] = 0;
		t = nd_term<double,3>( 1, p );
		f2.add( t );

		p[0] = 0; p[1] = 1; p[2] = 0;
		t = nd_term<double,3>( 1, p );
		f2.add( t );

		p[0] = 0; p[1] = 0; p[2] = 1;
		t = nd_term<double,3>( -1, p );
		f2.add( t );
/*
f3 = y + z2
*/
		p[0] = 0; p[1] = 1; p[2] = 0;
		t = nd_term<double,3>( 1, p );
		f3.add( t );

		p[0] = 0; p[1] = 0; p[2] = 2;
		t = nd_term<double,3>( 1, p );
		f3.add( t );

		f1.chop(0);
		f2.chop(0);
		f3.chop(0);

		s.push_back( f3 );
		s.push_back( f2 );
		s.push_back( f1 );

		qDebug() << "Input equations:";
		s.print( qDebug() );
		s.construct_groebner_basis();

		qDebug() << "Grobner basis:";
		s.print( qDebug() );
	}
    return 0;
}
